package com.echovin.esb.gateway.oauth2.handler;

import com.echovin.esb.gateway.oauth2.locator.ResourceLocator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * oauth2权限管理器
 * @author dym
 * @date 2019/12/17
 */
@Slf4j
@Component
public class OAuth2AccessDecisionManager {

    @Value("${esb.security.user-info-uri}")
    String checkTokenUrl;
    @Autowired
    ResourceLocator resourceLocator;
    @Autowired
    RestTemplate restTemplate;

    public OAuth2AccessDecisionManager() {
    }

    /**
     * 检查权限，检查该token能否访问该url
     * @param token
     * @param url
     * @param excludedAuthUrls
     * @return
     */
    public boolean checkPermission(String token, String url, String[] excludedAuthUrls) {
        boolean hasPermission = false;
        if (StringUtils.isEmpty(url)) {
            return hasPermission;
        }
        if (excludedAuthUrls != null && resourceLocator.matchUrl(excludedAuthUrls, url)) {
            return true;
        }
        if (StringUtils.isEmpty(token)) {
            return hasPermission;
        }
        // 第一步，请求授权中心，取出该token对应的角色id
        String URL = checkTokenUrl + "?access_token=" + token;

        List<Map<String, String>> roleIdList = null;
//        try {
            Map map = restTemplate.getForObject(URL, Map.class);
            roleIdList = (List<Map<String, String>>)map.get("authorities");
//        } catch (RestClientException e) {
//            log.error("请求授权中心，取出该token对应的角色id:{}", e);
//        }
        if (roleIdList == null || roleIdList.size() <= 0) {
            return hasPermission;
        }
        if (log.isDebugEnabled()) {
            log.debug("\n#########访问" + url + "该用户的权限是：" + roleIdList);
        }

        // 第二步，查询数据库，取出该url拥有权限的角色ids
        List<String> allRoleIdList = null;
//        try {
            allRoleIdList = resourceLocator.getResource(url);
//        } catch (IllegalArgumentException e) {
//            log.error("查询数据库，取出该url拥有权限的角色ids:{}", e);
//        }
        if (allRoleIdList == null || roleIdList.size() <= 0) {
            return hasPermission;
        }
        if (log.isDebugEnabled()) {
            log.debug("\n#########访问" + url + "需要的权限是：" + allRoleIdList);
        }

        // 第三步，匹配第一步和第二步的角色id
        Iterator iterator = allRoleIdList.iterator();
        while(iterator.hasNext()) {
            String needPermission = (String)iterator.next();
            // 无需权限
            if ("any".equals(needPermission)) {
                return true;
            }
            Iterator ite = roleIdList.iterator();
            while(ite.hasNext()) {
                Map<String, String> map1 = (Map<String, String>)ite.next();
                if (map1 == null) {
                    continue;
                }
                String str = map1.get("authority");
                if (str != null && str.equals(needPermission)) {
                    return true;
                }
            }
        }

        return hasPermission;
    }

}
